package com.du.dupload;

import java.util.ArrayList;
import java.util.List;

/**
 * Manually written background data loader. Loads text from the reader passed
 * and puts it to the UI through the callback passed. Note, that loader can be
 * executed only once.
 *
 * @author Eugene Matyushkin aka Skipy
 * @version $Id: CustomLoader.java 416 2010-07-26 14:22:39Z skipy_ru $
 * @since 09.07.2010
 */
public class CustomUploader implements Runnable, IUploader {

	/**
	 * Execution flag
	 */
	private boolean executed = false;

	/**
	 * UI callback
	 */
	protected IUICallback ui;

	private Integer startFrom;

	/**
	 * Data source
	 */
	private List<IVideoUploader> uploaders;

	/**
	 * Loader cancelation flag
	 */
	private boolean canceled = false;

	/**
	 * Created custom loader.
	 *
	 * @param ui
	 *            UI callback to use when publishing data and manipulating UI
	 * @param uploader
	 *            data source
	 */

	private ManagerCallback mc;

	public CustomUploader(IUICallback ui, List<IVideoUploader> uploaders,
			ManagerCallback mc, Integer startFrom) {
		this.ui = ui;
		this.uploaders = uploaders;
		this.mc = mc;
		this.startFrom = startFrom;
	}

	/**
	 * Starts this loader execution in separate thread
	 */
	@Override
	public synchronized void execute() throws IllegalStateException {
		if (executed) {
			throw new IllegalStateException("Uploader is already executed");
		}
		executed = true;
		Thread t = new Thread(this, "Custom uploader thread");
		t.start();
	}

	/**
	 * Loader main cycle
	 */
	@Override
	public void run() {
		int errCount = 0;
		List<String> res = new ArrayList<String>();
		for (int counter = startFrom; counter < uploaders.size(); counter++) {
			IVideoUploader uploader = uploaders.get(counter);
			uploader.initializeUpload();
			uploader.startUpload();
			ui.startLoading("Uploading files");
			ui.setInfo("file " + (counter + 1) + " of " + uploaders.size());
			// ui.setItemName(splitter.getName());
			StringBuilder sb = new StringBuilder();
			while (!isCanceled()) {
				// String str = reader.getNextLine();
				if (uploader.isCompleted() || uploader.isError()) {
					break;
				}
				// sb.append(str).append("\n");
				ui.setProgress(uploader.getProgressPercent());
				// ui.appendText(str + "\n");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException ex) {
					// Logger.getLogger(DownloadTorrent.class.getName()).log(Level.SEVERE,
					// null, ex);
				}
			}
			// ui.setText(sb.toString());
			// ui.stopLoading();
			uploader.stopUpload();
			uploader.close();

			if (uploader.isError() || isCanceled()) {
				errCount++;
				mc.taskDisrupted("");
				break;
			}
			if (uploader.isCompleted()) {
				ui.setProgress(100);
				res.addAll(uploader.getPath());
				mc.reportStatus(counter + 1);
			}
		}
		if (errCount == 0) {
			mc.setFinalData(res);
			mc.currentTaskIsFinished("Uploaded");
		}
	}

	/**
	 * Cancels current loading
	 */
	public synchronized void cancel() {
		canceled = true;
	}

	/**
	 * Checks whether execution was cancelled
	 *
	 * @return check result
	 */
	private synchronized boolean isCanceled() {
		return canceled;
	}
}
